<template>
  <div class="greenhouse-monitor">
    <!-- 监控主画面 -->
    <div class="monitor-main">
      <div class="monitor-status">实时监控 · 在线</div>
      <canvas id="monitor-canvas" class="monitor-img" style="width: 100%; height: 100%;"></canvas>
      <div class="monitor-info">
        <span class="monitor-location" id="main-monitor-location">{{ mainCameraLocation }}</span>
        <span class="monitor-time" id="main-monitor-time">{{ currentTime }}</span>
      </div>
    </div>

    <!-- 监控摄像头切换栏 -->
    <div class="monitor-cameras" id="monitor-cameras-container">
      <div
        v-for="(camera, index) in camerasData"
        :key="camera.id"
        :class="['camera-item', { active: index === 0 }]"
        :data-cam="camera.id"
        @click="selectCamera(camera, index)"
      >
        <img :src="formatImageUrl(camera.imageAddress)" :alt="camera.spNumber + '缩略图'" />
        <span>{{ camera.spNumber }}</span>
      </div>
    </div>


  </div>
</template>

<script setup lang="ts">
import '../css/reset.css'
import '../css/new_index.css'
import { ref, onMounted, onUnmounted, reactive } from 'vue'
import { getAccessToken } from '@/utils/auth'
import {useUserStore} from "@/store/modules/user"
// 动态引入JSMpeg库
// 注意：JSMpeg库将按需动态加载，无需提前导入

// 定义事件发射器，用于通知其他组件摄像头切换
const emit = defineEmits(['cameraChange'])

const currentTime = ref('')
const mainCameraLocation = ref('温室A区 - 番茄种植区')
const camerasData = ref<any[]>([])
const currentPlayer: any = ref(null)
const sensorData = reactive({
  temp: '24.6℃',
  humidity: '62%',
  light: '18600lux',
  co2: '420ppm',
  soil: '45%'
})

const tempStatus = ref('正常')
const humidityStatus = ref('正常')
const lightStatus = ref('偏高')
const co2Status = ref('正常')
const soilStatus = ref('正常')

const tempStatusClass = ref('normal')
const humidityStatusClass = ref('normal')
const lightStatusClass = ref('warning')
const co2StatusClass = ref('normal')
const soilStatusClass = ref('normal')

// 获取当前时间并格式化
const getCurrentTime = (): string => {
  const now = new Date()
  const year = now.getFullYear()
  const month = String(now.getMonth() + 1).padStart(2, '0')
  const day = String(now.getDate()).padStart(2, '0')
  const hours = String(now.getHours()).padStart(2, '0')
  const minutes = String(now.getMinutes()).padStart(2, '0')
  const seconds = String(now.getSeconds()).padStart(2, '0')
  return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
}

// 更新监控时间显示
const updateMonitorTime = (): void => {
  currentTime.value = getCurrentTime()
}

let timeInterval: number | null = null

// 获取URL参数中的token
const getQueryParam = (name: string): string | null => {
  const url = window.location.href
  name = name.replace(/[\[\]]/g, '\\$&')
  const regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)')
  const results = regex.exec(url)
  if (!results) return null
  if (!results[2]) return ''
  return decodeURIComponent(results[2].replace(/\+/g, ' '))
}

// 获取视频监控数据
const fetchCamerasData = async () => {
  try {
    // 获取token

// 获取用户信息
    let token = getAccessToken()

    // 如果URL中没有token，则尝试从localStorage获取
    if (!token) {
      const wsCache: any = (window as any).WebStorageCache
      if (wsCache) {
        const cache = new wsCache({
          storage: 'localStorage'
        })
        token = cache.get('ACCESS_TOKEN')
      }
    }

    // 构建URL，使用VITE_BASE_URL环境变量
    const baseUrl = import.meta.env.VITE_BASE_URL || ''
    const url = `${baseUrl}/admin-api/sp/SHP/page?pageNo=1&pageSize=10`

    // 准备请求选项
    const requestOptions: any = {
      method: 'GET',
      headers: {}
    }

    // 如果有token，则添加到请求头中
    if (token) {
      requestOptions.headers['Authorization'] = `Bearer ${token}`
    }

    const response = await fetch(url, requestOptions)
    const data = await response.json()

    if (data.code === 0) {
      camerasData.value = data.data.list.reverse()
      // 默认播放第一个摄像头
      if (camerasData.value.length > 0) {
        playCamera(camerasData.value[0])
        updateMainCameraInfo(camerasData.value[0])
        updateSensorData(camerasData.value[0])
      }
    }
  } catch (error) {
    console.error('获取摄像头数据失败:', error)
    // 使用默认数据进行演示
    useDefaultCameras()
  }
}

// 使用默认摄像头数据
const useDefaultCameras = () => {
  camerasData.value = [
    {
      id: 1,
      spNumber: '温室A区 - 番茄种植区',
      imageAddress: '/dp/img/demo_pic.png',
      spaddress: 'rtsp://localhost:8554/stream',
      cgqNumber1: 24.6,
      cgqNumber2: 62,
      cgqNumber3: 18600,
      cgqNumber4: 420,
      cgqNumber5: 45
    },
    {
      id: 2,
      spNumber: '温室B区 - 黄瓜种植区',
      imageAddress: '/dp/img/data_pic.png',
      spaddress: 'rtsp://localhost:8554/stream2',
      cgqNumber1: 26.2,
      cgqNumber2: 58,
      cgqNumber3: 15200,
      cgqNumber4: 380,
      cgqNumber5: 52
    }
  ]

  if (camerasData.value.length > 0) {
    playCamera(camerasData.value[0])
    updateMainCameraInfo(camerasData.value[0])
    updateSensorData(camerasData.value[0])
  }
}

// 确保JSMpeg库已加载
const ensureJSMpegLoaded = (): Promise<void> => {
  return new Promise((resolve, reject) => {
    const windowWithJSMpeg = window as any;
    // 1. 已加载：直接resolve
    if (windowWithJSMpeg.JSMpeg) {
      resolve();
      return;
    }
    // 2. 加载中：等待加载完成（避免重复加载）
    if (windowWithJSMpeg.JSMpegLoading) {
      const checkLoaded = setInterval(() => {
        if (windowWithJSMpeg.JSMpeg) {
          clearInterval(checkLoaded);
          resolve();
        }
      }, 50);
      return;
    }
    // 3. 未加载：开始加载
    windowWithJSMpeg.JSMpegLoading = true; // 标记为加载中
    const script = document.createElement('script');
    script.src = 'https://jsmpeg.com/jsmpeg.min.js';
    script.onload = () => {
      windowWithJSMpeg.JSMpegLoading = false;
      console.log('JSMpeg库加载成功');
      resolve();
    };
    script.onerror = () => {
      windowWithJSMpeg.JSMpegLoading = false;
      console.error('JSMpeg库加载失败');
      reject(new Error('JSMpeg库加载失败'));
    };
    document.head.appendChild(script);
  });
}

// 播放指定摄像头
const playCamera = async (camera: any) => {
  const canvas: HTMLCanvasElement | null = document.getElementById('monitor-canvas') as HTMLCanvasElement;
  if (!canvas || !camera.spAddress) return;

  // 1. 彻底销毁旧播放器（关键改进）
  if (currentPlayer.value) {
    try {
      // 暂停播放并停止所有内部定时器
      currentPlayer.value.pause();
      if (currentPlayer.value.timer) {
        clearInterval(currentPlayer.value.timer); // 清除JSMpeg内部定时器
      }
      // 销毁播放器实例
      currentPlayer.value.destroy();
      // 强制清除WebAssembly内存引用
      if (currentPlayer.value.source) {
        currentPlayer.value.source.close(); // 关闭数据源
      }
      if (currentPlayer.value.decoder) {
        currentPlayer.value.decoder.destroy(); // 销毁解码器
      }
      // 清除Canvas绘图缓存
      const ctx = canvas.getContext('2d');
      if (ctx) {
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        canvas.width = canvas.width; // 重置Canvas尺寸，强制清空缓存
      }
    } catch (err) {
      console.warn('销毁播放器异常:', err);
    } finally {
      currentPlayer.value = null; // 置空引用，释放内存
      console.log('旧播放器已彻底销毁');
    }
  }

  // 创建新的播放器实例
  // 注意：这里的端口需要与serve/index.js中配置的端口一致
  try {
    // 确保 JSMpeg 已正确引入
    await ensureJSMpegLoaded()

    if ((window as any).JSMpeg) {
      console.log("加载视频")
      console.log(btoa(camera.spAddress))
      //10.0.18.193
      currentPlayer.value = new (window as any).JSMpeg.Player(`ws://10.0.18.193:8033/rtsp?url=${btoa(camera.spAddress)}`, {
        canvas: canvas,
        disableAudio: true, // 禁用音频
        audio: false, // 双重禁用（兼容旧版本）
        pauseWhenHidden: false,
        autoplay: true,
        loop: false,
        // 新增：限制视频尺寸，避免渲染缓冲区过大
        maxWidth: canvas.clientWidth,
        maxHeight: canvas.clientHeight
      })
    } else {
      // 显示默认图片
      console.log("JSMpeg未加载")
      const ctx = canvas.getContext('2d')
      ctx.fillStyle = '#000'
      ctx.fillRect(0, 0, canvas.width, canvas.height)
      ctx.font = '20px Arial'
      ctx.fillStyle = '#fff'
      ctx.textAlign = 'center'
      ctx.fillText('视频加载中...', canvas.width/2, canvas.height/2)
    }
  } catch (error) {
    console.error('播放视频失败:', error)
    // 显示默认图片
    const ctx = canvas.getContext('2d')
    ctx.fillStyle = '#000'
    ctx.fillRect(0, 0, canvas.width, canvas.height)
    ctx.font = '20px Arial'
    ctx.fillStyle = '#fff'
    ctx.textAlign = 'center'
    ctx.fillText('视频加载失败', canvas.width/2, canvas.height/2)
  }
}

// 更新主画面信息
const updateMainCameraInfo = (camera: any) => {
  mainCameraLocation.value = camera.spNumber
}

// 更新传感器数据
const updateSensorData = (camera: any) => {
  sensorData.temp = camera.cgqNumber1 + '℃'
  sensorData.humidity = camera.cgqNumber2 + '%'
  sensorData.light = camera.cgqNumber3 + 'lux'
  sensorData.co2 = camera.cgqNumber4 + 'ppm'
  sensorData.soil = camera.cgqNumber5 + '%'

  // 更新状态显示
  updateStatus('temp', camera.cgqNumber1 < 20 ? '偏低' : camera.cgqNumber1 > 30 ? '偏高' : '正常')
  updateStatus('humidity', camera.cgqNumber2 < 50 ? '偏低' : camera.cgqNumber2 > 70 ? '偏高' : '正常')
  updateStatus('light', camera.cgqNumber3 < 10000 ? '偏低' : camera.cgqNumber3 > 20000 ? '偏高' : '正常')
  updateStatus('co2', camera.cgqNumber4 < 300 ? '偏低' : camera.cgqNumber4 > 500 ? '偏高' : '正常')
  updateStatus('soil', camera.cgqNumber5 < 30 ? '偏低' : camera.cgqNumber5 > 60 ? '偏高' : '正常')
}

// 更新状态显示
const updateStatus = (type: string, status: string) => {
  switch (type) {
    case 'temp':
      tempStatus.value = status
      tempStatusClass.value = status === '正常' ? 'normal' : 'warning'
      break
    case 'humidity':
      humidityStatus.value = status
      humidityStatusClass.value = status === '正常' ? 'normal' : 'warning'
      break
    case 'light':
      lightStatus.value = status
      lightStatusClass.value = status === '正常' ? 'normal' : 'warning'
      break
    case 'co2':
      co2Status.value = status
      co2StatusClass.value = status === '正常' ? 'normal' : 'warning'
      break
    case 'soil':
      soilStatus.value = status
      soilStatusClass.value = status === '正常' ? 'normal' : 'warning'
      break
  }
}

// 选择摄像头
const selectCamera = (camera: any, index: number) => {
  // 更新active状态
  const cameraItems = document.querySelectorAll('.camera-item')
  cameraItems.forEach((item, i) => {
    if (i === index) {
      item.classList.add('active')
    } else {
      item.classList.remove('active')
    }
  })

  // 播放选中的摄像头
  playCamera(camera)
  // 更新主画面信息
  updateMainCameraInfo(camera)
  // 更新传感器数据
  updateSensorData(camera)
  // 发射事件通知其他组件摄像头已切换
  emit('cameraChange', camera)
}

onMounted(() => {
  // 定时更新时间
  updateMonitorTime()
  timeInterval = window.setInterval(updateMonitorTime, 1000)

  // 获取摄像头数据
  fetchCamerasData()
})

onUnmounted(() => {
  // 1. 清除时间定时器
  if (timeInterval) {
    clearInterval(timeInterval);
    timeInterval = null;
  }

  // 2. 彻底销毁播放器
  if (currentPlayer.value) {
    currentPlayer.value.pause();
    currentPlayer.value.destroy();
    currentPlayer.value = null; // 置空，释放引用
    console.log('组件卸载：播放器已彻底销毁');
  }

  // 3. 清除JSMpeg全局变量（可选，避免页面残留）
  const windowWithJSMpeg = window as any;
  windowWithJSMpeg.JSMpegLoading = false;
});
</script>

<style scoped>
/* 已有样式保持不变 */

.monitor-main {
  position: relative;
  width: 102%;
  height: 87%;
  margin: 1% auto 0;
  border: 1px solid #00f5ff;
  border-radius: 4px;
  overflow: hidden;
}

.monitor-status {
  position: absolute;
  top: 1%;
  left: 1%;
  color: #0efcff;
  font-size: 0.6vw;
  z-index: 2;
  background: rgba(0, 0, 0, 0.5);
  padding: 2px 8px;
  border-radius: 3px;
}

.monitor-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.monitor-info {
  position: absolute;
  bottom: 0;
  left: 0;
  width: 100%;
  background: rgba(0, 0, 0, 0.6);
  color: #fff;
  padding: 5px 10px;
  font-size: 0.6vw;
  display: flex;
  justify-content: space-between;
}

.monitor-cameras {
  position: absolute;
  bottom: 1%;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  gap: 10px;
  z-index: 2;
}

.camera-item {
  width: 4vw;
  height: 3vw;
  border: 1px solid #666;
  border-radius: 3px;
  overflow: hidden;
  cursor: pointer;
  background: rgba(0, 0, 0, 0.7);
}

.camera-item.active {
  border-color: #0efcff;
  box-shadow: 0 0 8px #0efcff;
}

.camera-item img {
  width: 100%;
  height: 70%;
  object-fit: cover;
}

.camera-item span {
  display: block;
  font-size: 0.5vw;
  color: #fff;
  text-align: center;
  line-height: 30%;
  padding-top: 2px;
}

.monitor-data {
  width: 100%;
  height: 5%;
  background-color: rgba(0, 0, 0, 0.4);
  display: flex;
  align-items: center;
  justify-content: space-around;
  padding: 0 20px;
}

.data-item {
  display: flex;
  align-items: center;
  width: 16%;
}

.data-label {
  font-size: 0.65vw;
  color: #ccc;
  margin-right: 8px;
}

.data-value {
  font-size: 0.7vw;
  color: #fff;
  font-weight: 500;
  margin-right: 8px;
}

.data-status {
  font-size: 0.6vw;
  padding: 1px 6px;
  border-radius: 3px;
}

.data-status.normal {
  background-color: rgba(0, 255, 0, 0.3);
  color: #0f0;
}

.data-status.warning {
  background-color: rgba(255, 165, 0, 0.3);
  color: #ffa500;
}

.data-status.error {
  background-color: rgba(255, 0, 0, 0.3);
  color: #f00;
}
</style>

<script lang="ts">
/**
 * 格式化图片URL，将127.0.0.1:48080替换为当前环境的基础URL
 * @param url 图片URL
 */
const formatImageUrl = (url: string): string => {
  if (!url) return url

  // 获取当前环境的基础URL
  const baseUrl = import.meta.env.VITE_BASE_URL

  // 替换127.0.0.1:48080为当前基础URL
  return url.replace('http://127.0.0.1:48080', baseUrl)
}
</script>
